using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx;
using HarmonyLib;
using Hearthstone;
using Hearthstone.Progression;
using PegasusLettuce;
using PegasusShared;
using PegasusUtil;
using UnityEngine;

namespace Mercenary
{
    public static class UtilsNode
    {
        public static bool IsMysteryNode(uint nodeType)
        {
            return Array.IndexOf<uint>(new uint[]
            {
                0U,14U,18U,19U,23U,44U
            }, nodeType) > -1;
        }

        public static bool IsJumpNode(uint nodeType)
        {
            return nodeType == 18U;
        }

        public static bool IsBoss(uint nodeType)
        {
            return nodeType == 3U;
        }

        public static bool IsMonster(uint nodeType)
        {
            return Array.IndexOf<uint>(new uint[]
            {
                1U,2U,3U,22U
            }, nodeType) > -1;
        }

        //施法
        public static bool IsCaster(uint nodeType)
        {
            LettuceMapNodeTypeDbfRecord result = GameDbf.LettuceMapNodeType.GetRecord((int)nodeType);
            if (result == null)
                return false;
            // 			if (result.NodeVisualId == "OPPORTUNITY_CASTER")
            // 				Out.Log("IsCaster");
            return result.NodeVisualId == "OPPORTUNITY_CASTER";
        }

        //斗士
        public static bool IsFighter(uint nodeType)
        {
            LettuceMapNodeTypeDbfRecord result = GameDbf.LettuceMapNodeType.GetRecord((int)nodeType);
            if (result == null)
                return false;
            // 			if (result.NodeVisualId == "OPPORTUNITY_FIGHTER")
            // 				Out.Log("IsFighter");
            return result.NodeVisualId == "OPPORTUNITY_FIGHTER";
        }

        //护卫
        public static bool IsTank(uint nodeType)
        {
            LettuceMapNodeTypeDbfRecord result = GameDbf.LettuceMapNodeType.GetRecord((int)nodeType);
            if (result == null)
                return false;
            // 			if (result.NodeVisualId == "OPPORTUNITY_PROTECTOR")
            // 				Out.Log("IsTank");
            return result.NodeVisualId == "OPPORTUNITY_PROTECTOR";
        }
        public static bool IsDoctor(uint nodeType)
        {
            LettuceMapNodeTypeDbfRecord result = GameDbf.LettuceMapNodeType.GetRecord((int)nodeType);
            if (result == null)
                return false;
            // 			if (result.NodeVisualId == "HEALER")
            // 				Out.Log("IsDoctor");
            return result.NodeVisualId == "HEALER";
        }

        public static void SelectNextNode(LettuceMap map)
        {
            if (UtilsGui.modeConf.m_id == UiItemConst.模式_真人PVP.m_id)
            {
                Network.Get().RetireLettuceMap();
                Main.Sleep(2);
                return;
            }
            else if (UtilsGui.modeConf.m_id == UiItemConst.模式_挂机收菜.m_id)
            {
                if(!UtilsGui.needToHang)
                {
                    Network.Get().RetireLettuceMap();
                    Main.Sleep(5);
                    UtilsLog.Log(string.Format("[状态] 收菜时间截止，退出~"));
                    Application.Quit();
                }
                else
                {
                    UtilsGui.readyToHang = true;
                    UtilsLog.Log(string.Format("[状态] 下局战斗将写入收菜时间"));
                }
            }
            else if (UtilsGui.modeConf.m_id == UiItemConst.模式_自动佣兵任务.m_id)
            {
                TaskUtils.UpdateMercTask();
                UtilsLog.Log(string.Format("[状态] 更新任务状态完成"));
            }

            List<LettuceMapNode> nodes = map.NodeData;
            ValueTuple<LettuceMapNode, int> nextNode = GetNextNode(
                nodes.FindAll((LettuceMapNode n) => n.NodeState_ ==
                LettuceMapNode.NodeState.UNLOCKED), nodes);
            LettuceMapNode lettuceMapNode = nextNode.Item1;
            int item = nextNode.Item2;
            if (lettuceMapNode == null)
            {
                UtilsLog.Log("[节点选择] 没有找到神秘节点 重开");
                Network.Get().RetireLettuceMap();
                Main.Sleep(2);
                return;
            }
            if (!UtilsMap.m_bNeedComplete && item > 3)
            {
                UtilsLog.Log(string.Format("[节点选择] 通往神秘节点数{0}大于3 重开", item));
                Network.Get().RetireLettuceMap();
                Main.Sleep(2);
                return;
            }

            if (IsMonster(lettuceMapNode.NodeTypeId))
            {
                GameMgr gameMgr = GameMgr.Get();
                GameType gameType = GameType.GT_MERCENARIES_PVE;
                FormatType formatType = FormatType.FT_WILD;
                int missionId = 3790;
                int brawlLibraryItemId = 0;
                long deckId = 0L;
                string aiDeck = null;
                int? lettuceMapNodeId = new int?((int)lettuceMapNode.NodeId);
                UtilsLog.Log(string.Format("[节点选择] 怪物节点[NID:{0}][NTYPE:{1}] 进入战斗",
                    lettuceMapNode.NodeId, lettuceMapNode.NodeTypeId));
                gameMgr.FindGame(gameType, formatType, missionId,
                    brawlLibraryItemId, deckId, aiDeck, null, false, null,
                    lettuceMapNodeId, 0L, GameType.GT_UNKNOWN);
            }
            else
            {
                UtilsLog.Log(string.Format("[节点选择] 普通节点[NID:{0}][NTYPE:{1}]",
                    lettuceMapNode.NodeId, lettuceMapNode.NodeTypeId));
                Network.Get().ChooseLettuceMapNode(lettuceMapNode.NodeId);
            }
        }

        private static ValueTuple<LettuceMapNode, int> GetNextNode(
            List<LettuceMapNode> nodes, List<LettuceMapNode> allNodes)
        {
            int num = int.MaxValue;
            LettuceMapNode item = nodes[0];
            foreach (LettuceMapNode lettuceMapNode in nodes)
            {
                int minNode = GetMinNode(lettuceMapNode, 0, allNodes);
                if (minNode != -1 && minNode < num)
                {
                    item = lettuceMapNode;
                    num = minNode;
                }
            }
            if (num != int.MaxValue)
            {
                return new ValueTuple<LettuceMapNode, int>(item, num);
            }
            return new ValueTuple<LettuceMapNode, int>(null, 0);
        }

        // 最短路径
        private static int GetMinNode(LettuceMapNode node, int value, List<LettuceMapNode> nodes)
        {
            //全自动做任务，如果有赐福，需要走对应的点
			if (UtilsGui.modeConf.m_id == UiItemConst.模式_自动佣兵任务.m_id)
			{
				if ((TaskUtils.HaveTaskDocter && IsDoctor(node.NodeTypeId)) ||
					(TaskUtils.HaveTaskFighter && IsFighter(node.NodeTypeId)) ||
					(TaskUtils.HaveTaskCaster && IsCaster(node.NodeTypeId)) ||
					(TaskUtils.HaveTaskTank && IsTank(node.NodeTypeId)))
					return value;
			}

            // 需要不需要完成地图，只打到神秘人
			if (!UtilsMap.m_bNeedComplete)
            {
                if (IsMysteryNode(node.NodeTypeId)) return value;
                if (IsBoss(node.NodeTypeId)) return -1;
            }
            else
            {
                if (IsBoss(node.NodeTypeId)) return value;
            }

            int num = 0;
			if (UtilsGui.modeConf.m_id == UiItemConst.模式_自动主线任务.m_id ||
                UtilsGui.modeConf.m_id == UiItemConst.模式_自动解锁装备.m_id)
			{   //5.7改动 前两种为了不踩赐福
				if (IsCaster(node.NodeTypeId)
				|| IsFighter(node.NodeTypeId)
				|| IsTank(node.NodeTypeId))
					num = 99;
				else if (IsMonster(node.NodeTypeId))
					num = 1;
				else num = 0;
			}
			else
				num = (!IsMonster(node.NodeTypeId)) ? 0 : 1;

			if (node.ChildNodeIds.Count == 1)
            {
                return GetMinNode(nodes[(int)node.ChildNodeIds[0]], value + num, nodes);
            }
            int minNode = GetMinNode(nodes[(int)node.ChildNodeIds[0]], value + num, nodes);
            int minNode2 = GetMinNode(nodes[(int)node.ChildNodeIds[1]], value + num, nodes);
            if (minNode == -1) return minNode2;
            if (minNode2 == -1) return minNode;
            return Math.Min(minNode, minNode2);
        }
    }
}
